#ifndef LECTEURPHRASEAVECARBRE_H_
#define LECTEURPHRASEAVECARBRE_H_

#include "Symbole.h"
#include "LecteurSymbole.h"
#include "TableSymboles.h"
#include "Arbre.h"

#include <string>
using namespace std;

class LecteurPhraseAvecArbre {
    
  public:
	LecteurPhraseAvecArbre(string nomFich); // Construit un lecteur de phrase pour interpreter
                                                //  le programme dans le fichier nomFich

	void analyse();                         // Si le contenu du fichier est conforme à la grammaire,
                                                //   cette méthode se termine normalement et affiche un message "Syntaxe correcte".
                                                //   la table des symboles (ts) et l'arbre abstrait (arbre) auront été construits
                                                // Sinon, le programme sera interrompu (exit).

	inline TableSymboles getTs ()    { return ts;    } // accesseur	
	inline Noeud*        getArbre () { return arbre; } // accesseur
	

  private:
    LecteurSymbole ls;                          // le lecteur de symboles utilisé pour analyser le fichier
    TableSymboles  ts;                          // la table des symboles valués
    Noeud*         arbre;                       // l'arbre abstrait

//////////////////////// IMPLEMENTATION DE LA GRAMMAIRE ////////////////////////
    
    Noeud* programme();         // <programme>  ::= debut <seqInst> fin FIN_FICHIER
    Noeud* seqInst();           // <seqInst>    ::= <inst> ; { <inst> ; }
    Noeud* inst();              // <inst>       ::= <affectation> | <instSi> | <instTq> | <instRepeter> | <instLire> | <instEcrire>
    Noeud* instSi();            // <instSi>     ::= si ( <expBool> ) <seqInst> { sinonsi ( <expBool> ) <seqInst> } [ sinon <seqInst> ] finsi
    Noeud* instTq();            // <instTq>     ::= tantque ( <expBool> ) <seqInst> fintantque
    Noeud* instPour();          // <instPour>   ::= pour ( affectation ; <expBool>; affectation ) <seqInst> finpour
    Noeud* instRepeter();       // <instRepeter>::= repeter <seqInst> jusqua ( <expBool> )
    Noeud* instLire();          // <instLire>   ::= lire ( <variable> )
    Noeud* instEcrire();        // <instEcrire> ::= ecrire ( <expression> | <chaine> )
    Noeud* instSwitch();        // <instSwitch> ::= switch ( <variable> ) { cas ( <entier> ) <seqInst> break } [ defaut <seqInst> break]
    Noeud* instSelon();         //
    Noeud* affectation();       // <affectation>::= <variable> = <expression>
    Noeud* relation();          // <relation>   ::= <expression> { <opRel> <expression> }
    Noeud* expression();        // <expression> ::= <facteur> { <opBinaire> <facteur> }
    Noeud* terme();             // <terme>      ::= + | - | *  | /
    Noeud* facteur();           // <facteur>    ::= <entier>  |  <variable>  |  <opUnaire> <expBool>  |  ( <expBool> )

   //-------------------- Expressions et opérateurs booléens -------------------
    
    Noeud* expBoolET();         // <expBoolET>  ::= <relation> { <opBoolET> <relation> }
    Noeud* expBoolOU();         // <expBoolOU>  ::= <relation> { <opBoolOU> <relation> }      
    Symbole opBoolET();         // <opBool>     ::= et
    Symbole opBoolOU();         // <opBool>     ::= ou
    
   //-------------------------- Relations et opérateurs -----------------------   
    
    Symbole opRel();            // <opRel>      ::= == | != | < | <= | > | >=
    Symbole opUnaire();         // <opUnaire>   ::= - | non    
    Symbole opAdd();            // <opAdd>      ::= + | -
    Symbole opMult();           // <opMult>     ::= * | /

/////////////////////////////////////// OUTILS POUR SIMPLIFIER L'ANALYSE SYNTAXIQUE ///////////////////////////////////////////////
    
    void testerSymCour (string ch);  // si symbole courant != ch, erreur : on arrete le programme, sinon rien
    void sauterSymCour (string ch);  // si symbole courant == ch, on passe au symbole suivant, sinon erreur : on arrete
    void erreur (string mess);      // affiche le message d'erreur mess et arrete le programme
};

#endif /* LECTEURPHRASEAVECARBRE_H_ */
